<?php

if (! function_exists('value')) {
    /**
     * Return the default value of the given value.
     *
     * @param  mixed  $value
     * @return mixed
     */
    function value($value)
    {
        return $value instanceof Closure ? $value() : $value;
    }
}

if (! function_exists('define_from_env')) {
    /**
     * 从环境变量中定义常量
     * @param string $name
     * @param bool $default
     */
    function define_from_env($name, $default = false)
    {
        $env = getenv($name);
        if ($env) {
            define($name, $env);
        } else {
            define($name, $default);
        }
    }
}

if (! function_exists('env')) {
    /**
     * 从环境变量中读取值.
     *
     * @param  string  $key
     * @param  mixed   $default
     * @return mixed
     */
    function env($key, $default = null)
    {
        $value = getenv($key);
        if ($value === false) {
            if (defined($key)) {
                return constant($key);
            }
            return value($default);
        }
        switch (strtolower($value)) {
            case 'true':
            case '(true)':
                return true;
            case 'false':
            case '(false)':
                return false;
            case 'empty':
            case '(empty)':
                return '';
            case 'null':
            case '(null)':
                return null;
        }
        if (strlen($value) > 1 && stripos($value, '"') === 0 ) {

            $length = strlen($value);

            if(substr($value, -$length) === '"'){
                return substr($value, 1, -1);
            }
        }
        return $value;
    }
}

if(!function_exists('config')){
    /**
     * 获取配置信息
     * @param string $key
     * @param null|mixed $default
     * @return array|null
     */
    function config($key, $default = null){
        $di = Phalcon\Di\FactoryDefault::getDefault();
        $config = $di->getConfig();

        if(stripos($key,'.') === false){
            if( isset($config[$key])){
                return $config[$key];
            }
            return $default;
        }
        $keys = explode('.',$key);
        $value = $default;
        foreach ($keys as $key){
            if(isset($config->$key)){
                $config = $value = $config->$key;
            }else{
                return $value;
            }
        }
        return $value;
    }
}

if (! function_exists('class_basename')) {
    /**
     * Get the class "basename" of the given object / class.
     *
     * @param  string|object  $class
     * @return string
     */
    function class_basename($class)
    {
        $class = is_object($class) ? get_class($class) : $class;
        return basename(str_replace('\\', '/', $class));
    }
}
if (! function_exists('ends_with')) {
    /**
     * Determine if a given string ends with a given substring.
     *
     * @param  string  $haystack
     * @param  string|array  $needles
     * @return bool
     */
    function ends_with($haystack, $needles)
    {
        foreach ((array) $needles as $needle) {
            if (mb_substr($haystack, -mb_strlen($needle)) === (string) $needle) {
                return true;
            }
        }
        return false;
    }
}
if (! function_exists('starts_with')) {
    /**
     * Determine if a given string starts with a given substring.
     *
     * @param  string  $haystack
     * @param  string|array  $needles
     * @return bool
     */
    function starts_with($haystack, $needles)
    {
        foreach ((array) $needles as $needle) {
            if ($needle !== '' && mb_substr($haystack, 0, mb_strlen($needle)) === (string) $needle) {
                return true;
            }
        }
        return false;
    }
}

if (! function_exists('str_contains')) {
    /**
     * Determine if a given string contains a given substring.
     *
     * @param  string  $haystack
     * @param  string|array  $needles
     * @return bool
     */
    function str_contains($haystack, $needles)
    {
        foreach ((array) $needles as $needle) {
            if ($needle !== '' && mb_strpos($haystack, $needle) !== false) {
                return true;
            }
        }
        return false;
    }
}

if(!function_exists('response')){
    /**
     * 获取响应对象
     * @param string|null $content
     * @param int|null $code
     * @param string|null $status
     * @return \Baiyang\Http\Response
     */
    function response($content = null, $code = null, $status = null){
        return new Baiyang\Http\Response($content,$code,$status);
    }
}


if ( ! function_exists('set_cookie'))
{
    /**
     * Set cookie
     *
     * Accepts seven parameters, or you can submit an associative
     * array in the first parameter containing all the values.
     *
     * @param   string|array $name     Cookie name or array containing binds
     * @param   string       $value    The value of the cookie
     * @param   string       $expire   The number of seconds until expiration
     * @param   string       $domain   For site-wide cookie.
     *                                 Usually: .yourdomain.com
     * @param   string       $path     The cookie path
     * @param   bool         $secure   True makes the cookie secure
     * @param   bool         $httpOnly True makes the cookie accessible via
     *                                 http(s) only (no javascript)
     */
    function set_cookie($name, $value = '', $expire = '', $domain = '', $path = '/',$secure = false, $httpOnly = false)
    {
        $di = Phalcon\Di\FactoryDefault::getDefault();
        $cookie = $di->getShared('cookies');
        $cookie->set($name, $value, $expire, $path, $secure, $domain, $httpOnly);
    }
}
//--------------------------------------------------------------------
if ( ! function_exists('get_cookie'))
{
    /**
     * Fetch an item from the COOKIE array
     *
     * @param   string $name
     * @return  \Phalcon\Http\CookieInterface|null
     */
    function get_cookie($name)
    {
        $di = Phalcon\Di\FactoryDefault::getDefault();
        $cookie = $di->getShared('cookies');
        return $cookie->get($name);
    }
}
//--------------------------------------------------------------------
if ( ! function_exists('delete_cookie'))
{
    /**
     * Delete a COOKIE
     *
     * @param   mixed   $name
     * @return  bool
     */
    function delete_cookie($name)
    {
        $di = Phalcon\Di\FactoryDefault::getDefault();
        $cookie = $di->getShared('cookies');
        return $cookie->delete($name);
    }
}


if ( ! function_exists('random_string'))
{
    /**
     * Create a Random String
     *
     * Useful for generating passwords or hashes.
     *
     * @param    string $type Type of random string.  basic, alpha, alnum, numeric, nozero, unique, md5, sha1, and crypto
     * @param    int    $len  Number of characters
     *
     * @return    string
     */
    function random_string($type = 'alnum',  $len = 8)
    {
        switch ($type)
        {
            case 'basic':
                return mt_rand();
            case 'alnum':
            case 'numeric':
            case 'nozero':
            case 'alpha':
                switch ($type)
                {
                    case 'alpha':
                        $pool = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
                        break;
                    case 'alnum':
                        $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
                        break;
                    case 'numeric':
                        $pool = '0123456789';
                        break;
                    case 'nozero':
                        $pool = '123456789';
                        break;
                }
                return substr(str_shuffle(str_repeat($pool, ceil($len / strlen($pool)))), 0, $len);
            case 'md5':
                return md5(uniqid(mt_rand(), true));
            case 'sha1':
                return sha1(uniqid(mt_rand(), true));
            case 'crypto':
                return bin2hex(random_bytes($len/2));
        }
        return null;
    }
}


if(!function_exists('array_first')) {
    /**
     * 返回数组中的第一个值
     * @param array $array
     * @param callable|null $callback
     * @param null|mixed $default
     * @return mixed
     */
    function array_first($array, callable $callback = null, $default = null)
    {
        if (is_null($callback)) {
            if (empty($array)) {
                return value($default);
            }
            foreach ($array as $item) {
                return $item;
            }
        }
        foreach ($array as $key => $value) {
            if (call_user_func($callback, $value, $key)) {
                return $value;
            }
        }
        return value($default);
    }
}

if(!function_exists('array_value')) {
    /**
     * 如果是数组或可以以数组方式访问则返回 true 否则返回 false
     * @param $value
     * @return bool
     */
    function accessible($value)
    {
        return is_array($value) || $value instanceof ArrayAccess;
    }
}

if(!function_exists('array_value')) {
    /**
     * 获取数组中指定键的值，如果不存在则返回默认值
     * @param array $search
     * @param string $key
     * @param null|mixed $default
     * @return mixed
     */
    function array_value($key, $search, $default = null)
    {
        if (!accessible($search)) {
            return value($default);
        }
        if (is_null($key)) {
            return $search;
        }
        if (array_key_exists($key, $search)) {
            return $search[$key];
        }
        if (strpos($key, '.') === false) {
            return is_null($search[$key]) ? value($default) : $search[$key];
        }
        foreach (explode('.', $key) as $segment) {
            if (accessible($search) && array_key_exists($segment, $search)) {
                $search = $search[$segment];
            } else {
                return value($default);
            }
        }
        return $search;
    }

}

if(!function_exists('array_last')) {
    /**
     * 获取数组中最后一项值
     * @param array $array
     * @param callable|null $callback
     * @param null|mixed $default
     * @return mixed
     */
    function array_last($array, callable $callback = null, $default = null)
    {
        if (is_null($callback)) {
            return empty($array) ? value($default) : end($array);
        }
        return array_first(array_reverse($array, true), $callback, $default);
    }
}








